package com.example.matchingengine.service.strategy;

import com.example.matchingengine.model.Order;
import com.example.matchingengine.model.Order.OrderStatus;
import com.example.matchingengine.service.event.TradeEvent;
import com.example.matchingengine.service.model.OrderBook;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.LinkedList;

/**
 * 市价买单匹配策略
 */
@Slf4j
public class MarketBuyStrategy extends AbstractMatchingTemplate {
    
    @Override
    protected void doMatch(Order order, OrderBook orderBook) {
        matchMarketBuyOrder(order, orderBook);
    }
    
    @Override
    public String getStrategyType() {
        return "MARKET_BUY";
    }
    
    /**
     * 撮合市价买单
     * 市价买单会以当前最优卖价立即成交，直到买单完全成交或卖盘无订单
     */
    private void matchMarketBuyOrder(Order marketBuyOrder, OrderBook orderBook) {
        log.info("开始撮合市价买单: {}, 数量: {}", marketBuyOrder.getId(), marketBuyOrder.getQuantity());
        
        boolean fullyMatched = false;
        boolean hasMatched = false; // 标记是否有成交

        // 循环匹配卖盘订单，市价单需要立即成交
        while (!orderBook.getSellOrders().isEmpty() && !fullyMatched) {
            // 获取卖盘最低价格
            BigDecimal lowestSellPrice = orderBook.getSellOrders().firstKey();

            // 获取该价格下的订单列表
            LinkedList<Order> ordersAtPrice = orderBook.getSellOrders().get(lowestSellPrice);
            if (ordersAtPrice.isEmpty()) {
                orderBook.getSellOrders().remove(lowestSellPrice);
                continue;
            }

            // 获取该价格下最早的订单（时间优先）
            Order sellOrder = ordersAtPrice.getFirst();

            // 计算可成交数量
            BigDecimal remainingBuyQty = marketBuyOrder.getQuantity().subtract(marketBuyOrder.getFilledQuantity());
            BigDecimal remainingSellQty = sellOrder.getQuantity().subtract(sellOrder.getFilledQuantity());
            BigDecimal matchQty = remainingBuyQty.min(remainingSellQty);

            // 更新订单成交数量
            marketBuyOrder.setFilledQuantity(marketBuyOrder.getFilledQuantity().add(matchQty));
            sellOrder.setFilledQuantity(sellOrder.getFilledQuantity().add(matchQty));
            hasMatched = true; // 标记有成交

            // 生成成交事件，市价买单以卖单价格成交
            TradeEvent tradeEvent = new TradeEvent(
                    marketBuyOrder.getId(),
                    sellOrder.getId(),
                    orderBook.getSymbol(),
                    sellOrder.getPrice(), // 市价买单以卖单价格成交
                    matchQty,
                    LocalDateTime.now()
            );

            // 发送成交消息到RocketMQ
            orderBook.sendTradeEvent(tradeEvent);

            // 记录成交计数
            orderBook.incrementTradeCounter();

            // 检查卖单是否完全成交
            if (sellOrder.getFilledQuantity().compareTo(sellOrder.getQuantity()) >= 0) {
                // 从卖盘移除已完全成交的订单
                Order removedOrder = ordersAtPrice.removeFirst();
                // 从订单映射表中移除
                orderBook.getOrderMap().remove(removedOrder.getId());
                if (ordersAtPrice.isEmpty()) {
                    orderBook.getSellOrders().remove(lowestSellPrice);
                }
                sellOrder.setStatus(OrderStatus.FILLED);
                sellOrder.setUpdateTime(LocalDateTime.now());

                // 发送订单状态更新消息
                orderBook.sendOrderStatusUpdate(sellOrder);
            } else {
                // 部分成交
                sellOrder.setStatus(OrderStatus.PARTIALLY_FILLED);
                sellOrder.setUpdateTime(LocalDateTime.now());

                // 发送订单状态更新消息
                orderBook.sendOrderStatusUpdate(sellOrder);
            }

            // 检查市价买单是否完全成交
            if (marketBuyOrder.getFilledQuantity().compareTo(marketBuyOrder.getQuantity()) >= 0) {
                marketBuyOrder.setStatus(OrderStatus.FILLED);
                fullyMatched = true;
                log.info("市价买单完全成交: {}", marketBuyOrder.getId());
            } else {
                marketBuyOrder.setStatus(OrderStatus.PARTIALLY_FILLED);
            }

            marketBuyOrder.setUpdateTime(LocalDateTime.now());
        }

        // 市价单如果未完全成交，标记为部分成交（不加入订单簿）
        if (!fullyMatched) {
            log.warn("市价买单未完全成交，剩余数量: {}, 订单ID: {}", 
                    marketBuyOrder.getQuantity().subtract(marketBuyOrder.getFilledQuantity()), 
                    marketBuyOrder.getId());
            // 市价单不加入订单簿，设置最终状态
            if (marketBuyOrder.getFilledQuantity().compareTo(BigDecimal.ZERO) > 0) {
                marketBuyOrder.setStatus(OrderStatus.PARTIALLY_FILLED_CANCELED);
            } else {
                // 如果完全没有成交，标记为拒绝
                marketBuyOrder.setStatus(OrderStatus.REJECTED);
                log.warn("市价买单完全无法成交，标记为拒绝: {}", marketBuyOrder.getId());
            }
        }

        // 市价单总是需要发送状态更新消息（包括REJECTED状态）
        // 但对于完全没有成交的情况，只有状态变为REJECTED时才发送
        if (hasMatched || marketBuyOrder.getStatus() == OrderStatus.REJECTED) {
            orderBook.sendOrderStatusUpdate(marketBuyOrder);
        }
    }
}